package com.wangshouyu.log.aop;

import com.wangshouyu.log.annotation.AopRequestLog;
import com.wangshouyu.log.enums.LogLevel;
import com.wangshouyu.log.print.LogPrint;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;

import java.lang.reflect.Method;

/**
 * @author 王守钰
 * @description Aop日志拦截器
 * @date 2020/7/23 9:14
 */
public class AopRequestLogInterceptor implements MethodInterceptor {

    private Logger log = LoggerFactory.getLogger(AopRequestLogInterceptor.class);

    private LogPrint logPrint;

    public void setLogPrint(LogPrint logPrint) {
        this.logPrint = logPrint;
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 日志级别
        LogLevel logLevel = LogLevel.INFO;
        // 打印返回结果
        Boolean printResult = true;
        // 是否启用打印日志
        Boolean enable = Boolean.FALSE;
        try{
            // 获取请求方法
            Method method = invocation.getMethod();
            // 构建SpEL
            LocalVariableTableParameterNameDiscoverer paramNames = new LocalVariableTableParameterNameDiscoverer();
            // 获取类上是否有注解
            AopRequestLog classAnnotation = invocation.getMethod().getDeclaringClass().getAnnotation(AopRequestLog.class);
            if(null != classAnnotation && classAnnotation.enable()){
                // 设置日志等级
                logLevel = classAnnotation.logLevel();
                // 打印返回结果
                printResult = classAnnotation.printResult();
                // 是否启用了打印日志
                enable = classAnnotation.enable();
            }
            // 请求日志参数
            AopRequestLog requestAnnotation = method.getAnnotation(AopRequestLog.class);
            // 获取参数名称
            String[] parameterNames = paramNames.getParameterNames(method);
            // 判断方法上是否有自定义注解
            if(null != requestAnnotation){
                // 设置日志等级
                logLevel = requestAnnotation.logLevel();
                // 打印返回结果
                printResult = requestAnnotation.printResult();
                // 设置想要获取的参数
                if(null != requestAnnotation.args()){
                    parameterNames = requestAnnotation.args();
                }
                enable = requestAnnotation.enable();
            }

            if(enable){
                logPrint.request(logLevel, method, invocation.getArguments(), parameterNames);
            }
        }catch (Exception e){
            log.error("记录请求日志失败");
            log.error(e.getMessage(), e);
        }

        Object proceed = invocation.proceed();
        if(printResult && enable){
            logPrint.result(logLevel, proceed);
        }
        return proceed;
    }

}
